#include <vector>
#include <complex>
#include <cmath>
#include <stdexcept>
#include <algorithm>

typedef std::complex<float> Complex;

class FarrowInterpolatorIQ_Cpp11 {
public:
    FarrowInterpolatorIQ_Cpp11() {
        // 立方插值系数矩阵 (C++11初始化列表)
        coeffs_.resize(4);
        coeffs_[0] = { 0.0f,  0.0f,  0.0f,  0.0f };  // h0
        coeffs_[1] = { 1.0f,  0.5f, -0.5f,  0.5f };  // h1
        coeffs_[2] = { 0.0f,  0.5f,  1.0f, -0.5f };  // h2
        coeffs_[3] = { 0.0f,  0.0f, -0.5f,  0.5f };  // h3
        taps_ = 4;
    }

    std::vector<Complex> resample(const std::vector<Complex>& iq_in,
        int up_rate, int down_rate) {
        // 参数检查 (C++11 static_assert不适用运行时检查)
        if (up_rate <= 0 || down_rate <= 0) {
            throw std::invalid_argument("采样率必须为正数");
        }
        if (iq_in.size() < static_cast<size_t>(taps_)) {
            throw std::invalid_argument("输入数据过短");
        }

        // 计算输出长度 (C++11兼容的rounding)
        const double ratio = static_cast<double>(up_rate) / down_rate;
        const size_t out_len = static_cast<size_t>(
            std::ceil(iq_in.size() * ratio));
        std::vector<Complex> iq_out(out_len);

        // 边界扩展 (C++11 lambda实现填充)
        std::vector<Complex> padded_iq;
        pad_iq_data(iq_in, padded_iq);

        // 主处理循环
        for (size_t n = 0; n < out_len; ++n) {
            const double virtual_index = n / ratio;
            const size_t base_idx = static_cast<size_t>(virtual_index);
            const float mu = static_cast<float>(virtual_index - base_idx);

            // 分别处理I和Q分量
            float sum_i = 0.0f, sum_q = 0.0f;
            for (int m = 0; m < taps_; ++m) {
                // Horner法则 (C++11兼容写法)
                const float* c = &coeffs_[m][0];
                const float poly = ((c[3] * mu + c[2]) * mu + c[1]) * mu + c[0];

                sum_i += poly * padded_iq[base_idx + m].real();
                sum_q += poly * padded_iq[base_idx + m].imag();
            }
            iq_out[n] = Complex(sum_i, sum_q);
        }

        return iq_out;
    }

private:
    std::vector<std::vector<float>> coeffs_;
    int taps_;

    void pad_iq_data(const std::vector<Complex>& input,
        std::vector<Complex>& padded) {
        const int pad_len = taps_ / 2;
        padded.reserve(input.size() + 2 * pad_len);

        // 前端填充 (C++11范围for循环)
        for (int i = pad_len; i > 0; --i) {
            padded.push_back(std::conj(input[pad_len - i]));
        }

        // 原始数据 (C++11移动语义优化)
        padded.insert(padded.end(), input.begin(), input.end());

        // 后端填充
        for (int i = 1; i <= pad_len; ++i) {
            padded.push_back(std::conj(input[input.size() - i - 1]));
        }
    }
};